package com.example.demo;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.text.SimpleDateFormat;

/**
 * 应急预案管理Servlet：处理应急预案的CRUD操作及与火灾报警的关联
 */
@WebServlet(name = "EmergencyPlanServlet", value = "/EmergencyPlanServlet")
public class EmergencyPlanServlet extends HttpServlet {
    // 数据库连接信息（与火灾报警共用）
    private static final String DB_URL = "jdbc:mysql://172.18.64.254:3306/三人行?useSSL=false&serverTimezone=UTC&characterEncoding=utf8";
    private static final String DB_USER = "webdb";
    private static final String DB_PASSWORD = "webdb";

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();

        String action = request.getParameter("action");
        if ("list".equals(action)) {
            // 分页查询应急预案列表（支持按类型、区域筛选）
            listPlans(request, out);
        } else if ("get".equals(action)) {
            // 获取单个应急预案详情
            getPlanById(request, out);
        } else if ("delete".equals(action)) {
            // 删除应急预案
            deletePlan(request, out);
        } else if ("getByAlarm".equals(action)) {
            // 根据报警ID查询关联的应急预案
            getPlansByAlarmId(request, out);
        } else {
            out.println("{\"error\": \"无效的GET操作(action)\"}");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();

        String action = request.getParameter("action");
        if ("add".equals(action)) {
            // 添加新应急预案
            addPlan(request, out);
        } else if ("update".equals(action)) {
            // 更新应急预案
            updatePlan(request, out);
        } else if ("relate".equals(action)) {
            // 关联报警记录与应急预案
            relateAlarmAndPlan(request, out);
        } else {
            out.println("{\"error\": \"无效的POST操作(action)\"}");
        }
    }


    /**
     * 1. 查询应急预案列表（支持按类型、区域筛选）
     */
    private void listPlans(HttpServletRequest request, PrintWriter out) {
        String planType = request.getParameter("type") == null ? "" : request.getParameter("type");
        String area = request.getParameter("area") == null ? "" : request.getParameter("area");

        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(
                     "SELECT * FROM emergency_plan " +
                             "WHERE (plan_type LIKE ? OR ? = '') " +
                             "AND (applicable_area LIKE ? OR ? = '') " +
                             "ORDER BY create_time DESC"
             )) {

            pstmt.setString(1, "%" + planType + "%");
            pstmt.setString(2, planType);
            pstmt.setString(3, "%" + area + "%");
            pstmt.setString(4, area);

            ResultSet rs = pstmt.executeQuery();
            StringBuilder json = new StringBuilder("[");
            while (rs.next()) {
                if (json.length() > 1) json.append(",");
                json.append("{")
                        .append("\"id\":").append(rs.getInt("id")).append(",")
                        .append("\"planName\":\"").append(escapeJson(rs.getString("plan_name"))).append("\",")
                        .append("\"planType\":\"").append(escapeJson(rs.getString("plan_type"))).append("\",")
                        .append("\"content\":\"").append(escapeJson(rs.getString("content"))).append("\",")
                        .append("\"applicableArea\":\"").append(escapeJson(rs.getString("applicable_area"))).append("\",")
                        .append("\"createTime\":\"").append(formatDateTime(rs.getTimestamp("create_time"))).append("\",")
                        .append("\"status\":\"").append(rs.getString("status")).append("\"")
                        .append("}");
            }
            json.append("]");
            out.println(json.toString());

        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"查询失败：" + e.getMessage() + "\"}");
        }
    }


    /**
     * 2. 根据ID获取单个应急预案详情
     */
    private void getPlanById(HttpServletRequest request, PrintWriter out) {
        String idParam = request.getParameter("id");
        if (idParam == null || idParam.trim().isEmpty()) {
            out.println("{\"error\": \"缺少参数：id\"}");
            return;
        }

        try {
            int id = Integer.parseInt(idParam);
            try (Connection conn = getConnection();
                 PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM emergency_plan WHERE id = ?")) {

                pstmt.setInt(1, id);
                ResultSet rs = pstmt.executeQuery();

                if (rs.next()) {
                    StringBuilder json = new StringBuilder("{");
                    json.append("\"id\":").append(rs.getInt("id")).append(",")
                            .append("\"planName\":\"").append(escapeJson(rs.getString("plan_name"))).append("\",")
                            .append("\"planType\":\"").append(escapeJson(rs.getString("plan_type"))).append("\",")
                            .append("\"content\":\"").append(escapeJson(rs.getString("content"))).append("\",")
                            .append("\"applicableArea\":\"").append(escapeJson(rs.getString("applicable_area"))).append("\",")
                            .append("\"createTime\":\"").append(formatDateTime(rs.getTimestamp("create_time"))).append("\",")
                            .append("\"status\":\"").append(rs.getString("status")).append("\"")
                            .append("}");
                    out.println(json.toString());
                } else {
                    out.println("{\"error\": \"未找到ID为" + id + "的预案\"}");
                }
            }
        } catch (NumberFormatException e) {
            out.println("{\"error\": \"id格式错误：" + idParam + "\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"查询失败：" + e.getMessage() + "\"}");
        }
    }


    /**
     * 3. 添加新应急预案
     */
    private void addPlan(HttpServletRequest request, PrintWriter out) {
        String planName = request.getParameter("planName");
        String planType = request.getParameter("planType");
        String content = request.getParameter("content");
        String applicableArea = request.getParameter("applicableArea");
        String status = request.getParameter("status") == null ? "启用" : request.getParameter("status");

        // 参数校验
        if (planName == null || planType == null || content == null || applicableArea == null) {
            out.println("{\"error\": \"缺少必要参数（planName/planType/content/applicableArea）\"}");
            return;
        }

        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(
                     "INSERT INTO emergency_plan (plan_name, plan_type, content, applicable_area, status) " +
                             "VALUES (?, ?, ?, ?, ?)"
             )) {

            pstmt.setString(1, planName);
            pstmt.setString(2, planType);
            pstmt.setString(3, content);
            pstmt.setString(4, applicableArea);
            pstmt.setString(5, status);
            pstmt.executeUpdate();

            out.println("{\"success\": true, \"message\": \"添加成功\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"添加失败：" + e.getMessage() + "\"}");
        }
    }


    /**
     * 4. 更新应急预案
     */
    private void updatePlan(HttpServletRequest request, PrintWriter out) {
        String idParam = request.getParameter("id");
        String planName = request.getParameter("planName");
        String planType = request.getParameter("planType");
        String content = request.getParameter("content");
        String applicableArea = request.getParameter("applicableArea");
        String status = request.getParameter("status");

        // 参数校验
        if (idParam == null || planName == null || planType == null || content == null || applicableArea == null) {
            out.println("{\"error\": \"缺少必要参数（id/planName/planType/content/applicableArea）\"}");
            return;
        }

        try {
            int id = Integer.parseInt(idParam);
            try (Connection conn = getConnection();
                 PreparedStatement pstmt = conn.prepareStatement(
                         "UPDATE emergency_plan SET " +
                                 "plan_name = ?, plan_type = ?, content = ?, applicable_area = ?, status = ?, update_time = NOW() " +
                                 "WHERE id = ?"
                 )) {

                pstmt.setString(1, planName);
                pstmt.setString(2, planType);
                pstmt.setString(3, content);
                pstmt.setString(4, applicableArea);
                pstmt.setString(5, status);
                pstmt.setInt(6, id);

                int rows = pstmt.executeUpdate();
                if (rows > 0) {
                    out.println("{\"success\": true, \"message\": \"更新成功\"}");
                } else {
                    out.println("{\"error\": \"未找到ID为" + id + "的预案\"}");
                }
            }
        } catch (NumberFormatException e) {
            out.println("{\"error\": \"id格式错误：" + idParam + "\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"更新失败：" + e.getMessage() + "\"}");
        }
    }


    /**
     * 5. 删除应急预案
     */
    private void deletePlan(HttpServletRequest request, PrintWriter out) {
        String idParam = request.getParameter("id");
        if (idParam == null || idParam.trim().isEmpty()) {
            out.println("{\"error\": \"缺少参数：id\"}");
            return;
        }

        try {
            int id = Integer.parseInt(idParam);
            try (Connection conn = getConnection();
                 PreparedStatement pstmt = conn.prepareStatement("DELETE FROM emergency_plan WHERE id = ?")) {

                pstmt.setInt(1, id);
                int rows = pstmt.executeUpdate();
                if (rows > 0) {
                    out.println("{\"success\": true, \"message\": \"删除成功\"}");
                } else {
                    out.println("{\"error\": \"未找到ID为" + id + "的预案\"}");
                }
            }
        } catch (NumberFormatException e) {
            out.println("{\"error\": \"id格式错误：" + idParam + "\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"删除失败：" + e.getMessage() + "\"}");
        }
    }


    /**
     * 6. 关联火灾报警与应急预案（1个报警可关联1个预案，重复关联会覆盖）
     */
    private void relateAlarmAndPlan(HttpServletRequest request, PrintWriter out) {
        String alarmIdParam = request.getParameter("alarmId");
        String planIdParam = request.getParameter("planId");

        // 参数校验
        if (alarmIdParam == null || planIdParam == null) {
            out.println("{\"error\": \"缺少必要参数（alarmId/planId）\"}");
            return;
        }

        try {
            int alarmId = Integer.parseInt(alarmIdParam);
            int planId = Integer.parseInt(planIdParam);

            try (Connection conn = getConnection()) {
                // 先删除该报警已有的关联（确保1对1关联）
                PreparedStatement deleteStmt = conn.prepareStatement(
                        "DELETE FROM alarm_plan_relation WHERE alarm_id = ?"
                );
                deleteStmt.setInt(1, alarmId);
                deleteStmt.executeUpdate();

                // 添加新关联
                PreparedStatement insertStmt = conn.prepareStatement(
                        "INSERT INTO alarm_plan_relation (alarm_id, plan_id) VALUES (?, ?)"
                );
                insertStmt.setInt(1, alarmId);
                insertStmt.setInt(2, planId);
                insertStmt.executeUpdate();

                out.println("{\"success\": true, \"message\": \"关联成功\"}");
            }
        } catch (NumberFormatException e) {
            out.println("{\"error\": \"alarmId或planId格式错误\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"关联失败：" + e.getMessage() + "\"}");
        }
    }


    /**
     * 7. 根据报警ID查询关联的应急预案
     */
    private void getPlansByAlarmId(HttpServletRequest request, PrintWriter out) {
        String alarmIdParam = request.getParameter("alarmId");
        if (alarmIdParam == null) {
            out.println("{\"error\": \"缺少参数：alarmId\"}");
            return;
        }

        try {
            int alarmId = Integer.parseInt(alarmIdParam);
            try (Connection conn = getConnection();
                 PreparedStatement pstmt = conn.prepareStatement(
                         "SELECT p.* FROM emergency_plan p " +
                                 "JOIN alarm_plan_relation r ON p.id = r.plan_id " +
                                 "WHERE r.alarm_id = ?"
                 )) {

                pstmt.setInt(1, alarmId);
                ResultSet rs = pstmt.executeQuery();

                StringBuilder json = new StringBuilder("[");
                while (rs.next()) {
                    if (json.length() > 1) json.append(",");
                    json.append("{")
                            .append("\"id\":").append(rs.getInt("id")).append(",")
                            .append("\"planName\":\"").append(escapeJson(rs.getString("plan_name"))).append("\",")
                            .append("\"planType\":\"").append(escapeJson(rs.getString("plan_type"))).append("\",")
                            .append("\"content\":\"").append(escapeJson(rs.getString("content"))).append("\",")
                            .append("\"applicableArea\":\"").append(escapeJson(rs.getString("applicable_area"))).append("\"")
                            .append("}");
                }
                json.append("]");
                out.println(json.toString());

            }
        } catch (NumberFormatException e) {
            out.println("{\"error\": \"alarmId格式错误：" + alarmIdParam + "\"}");
        } catch (SQLException e) {
            e.printStackTrace();
            out.println("{\"error\": \"查询失败：" + e.getMessage() + "\"}");
        }
    }


    /**
     * 工具方法：JSON特殊字符转义（避免双引号、换行等破坏JSON格式）
     */
    private String escapeJson(String value) {
        if (value == null) return "";
        return value.replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("\b", "\\b")
                .replace("\f", "\\f")
                .replace("\n", "\\n")
                .replace("\r", "\\r")
                .replace("\t", "\\t");
    }


    /**
     * 工具方法：日期格式化
     */
    private String formatDateTime(Timestamp timestamp) {
        if (timestamp == null) return "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        return sdf.format(timestamp);
    }


    /**
     * 工具方法：获取数据库连接
     */
    private Connection getConnection() throws SQLException {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");  // 加载MySQL驱动
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new SQLException("JDBC驱动加载失败", e);
        }
        return DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
    }
}